package utils

import (
	"fmt"
	"net/smtp"
	"strings"
)

type MailConfig struct {
	User   string `json:"user" bson:"user" validate:"required"`
	Pwd    string `json:"password" bson:"password" validate:"required"`
	Server string `json:"server" bson:"server" validate:"required"`
}

type MailType string

func (t *MailType) String() string {
	switch *t {
	case MailHTML:
		return "Content-Type: text/html; charset=UTF-8"
	default:
		return "Content-Type: text/plain; charset=UTF-8"
	}
}

const (
	MailHTML MailType = "html"
	MailTEXT MailType = "text"
)

type MailSender struct {
	conf *MailConfig
}

var mailInst *MailSender

func MailManager() *MailSender {
	if nil == mailInst {
		mailInst = &MailSender{}
	}
	return mailInst
}

func (m *MailSender) Config(c *MailConfig) error {
	validater := GetValidate()
	if err := validater.Struct(c); err != nil {
		return fmt.Errorf("Error : MailConf %s", err)
	}
	m.conf = c
	return nil
}

func (m *MailSender) Mail(to []string, subject, body string, mailType MailType) error {
	if nil == m.conf {
		return fmt.Errorf("config not set")
	}
	if len(to) == 0 {
		return fmt.Errorf("Mail to is nil")
	}
	for _, mail := range to {
		if b, err := CheckMail(mail); !b || err != nil {
			return fmt.Errorf("mail %s is not mail address", mail)
		}
	}
	mail_to := Join(to, ";")

	// 拼接消息体
	var contentType = mailType.String()
	msg := []byte("To: " + mail_to + "\r\nFrom: " + m.conf.User + "\r\nSubject: " + subject + "\r\n" + contentType + "\r\n\r\n" + body)

	// msg 内容输出查看
	Debug("To: " + mail_to + "\r\n" +
		"From: " + m.conf.User + "\r\n" +
		"Subject: " + subject + "\r\n" +
		"" + contentType + "\r\n\r\n" +
		"" + body)

	// 进行身份认证
	hp := strings.Split(m.conf.Server, ":")
	auth := smtp.PlainAuth("", m.conf.User, m.conf.Pwd, hp[0])

	return smtp.SendMail(m.conf.Server, auth, m.conf.User, to, msg)
}
